# a typical argument could be "--system-site-packages"
VIRTUALENV_CREATE_ARGUMENTS ?=

# when using virtualenv sys.real_prefix is set and we use the path to the python
# binary to determine the actual location of the virtualenv. In any other case
# we fallback to the VIRTUAL_ENV variable or the `.venv` directory
DIR_VIRTUALENV := $(shell echo "import sys; hasattr(sys, 'real_prefix') or sys.exit(1)" | "$(PYTHON_BIN)" && \
	echo "$$(dirname "$$(dirname "$$(which python)")")" || echo "$${VIRTUAL_ENV:-"$(DIR_BUILD)/venv"}")
ACTIVATE_VIRTUALENV ?= $(DIR_VIRTUALENV)/bin/activate
VIRTUALENV_STAMP = $(DIR_VIRTUALENV)/.stamp_virtualenv
# Pre-dependencies need to be met before the virtualenv is generated.
# The "wheel" dependency is necessary for many packages built via pip.
VIRTUALENV_PREDEPENDENCIES ?= venv wheel

# prepend all python calls with the virtualenv activation
RUN_PYTHON = . "$(ACTIVATE_VIRTUALENV)" && "$(PYTHON_BIN)"

# add dependencies for the virtualenv to related targets
install-python: $(VIRTUALENV_STAMP)
dist-python: $(VIRTUALENV_STAMP)
test-python: $(VIRTUALENV_STAMP)
report-python-coverage: $(VIRTUALENV_STAMP)


.PHONY: help-python-virtualenv
help-python-virtualenv:
	@echo "Targets related to virtualenv (Python):"
	@echo "    virtualenv-check"
	@echo "    virtualenv-update"
	@echo

help-python: help-python-virtualenv

# Check if all required modules for preparing a virtual environment are available.
# Emit helpful errors in case of missing modules.
.PHONY: virtualenv-dependency-check
virtualenv-predependency-check:
	@for module in $(VIRTUALENV_PREDEPENDENCIES); do \
		if ! "$(PYTHON_BIN)" -c "import $$module"; then \
			echo >&2 "ERROR: missing python module '$$module'.  Installation hint: apt install python3-$$module"; exit 1; \
		fi; done

$(ACTIVATE_VIRTUALENV): virtualenv-predependency-check
	@if [ ! -e "$(ACTIVATE_VIRTUALENV)" ]; then "$(PYTHON_BIN)" -m venv $(VIRTUALENV_CREATE_ARGUMENTS) "$(DIR_VIRTUALENV)"; fi

.PHONY: virtualenv-check
virtualenv-check: $(ACTIVATE_VIRTUALENV)

$(VIRTUALENV_STAMP): $(VIRTUALENV_REQUIREMENTS_FILE) $(ACTIVATE_VIRTUALENV)
	if [ -z "$${VIRTUAL_ENV:-}" ]; then . "$(ACTIVATE_VIRTUALENV)"; fi \
		&& for dep in $(VIRTUALENV_PREDEPENDENCIES); do "$(PYTHON_BIN)" -c "import $$dep" 2>/dev/null || "$(PYTHON_BIN)" -m pip install "$$dep"; done \
		&& "$(PYTHON_BIN)" -m pip install -r "$(VIRTUALENV_REQUIREMENTS_FILE)"
	touch "$(VIRTUALENV_STAMP)"

.PHONY: virtualenv-update
virtualenv-update: $(VIRTUALENV_STAMP)

.PHONY: clean-python-virtualenv
clean-python-virtualenv:
	$(RM) -r "$(DIR_VIRTUALENV)"

clean-python: clean-python-virtualenv
